import matplotlib.pyplot as plt
from sklearn import neighbors
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import AffinityPropagation
import scipy.io as scio
from sklearn.decomposition import PCA
from numpy import unique
from numpy import where
import ann as ann
import numpy as np
import h5py as h5


# import sklearn.datasets

def init_sample():
    """
    第一步：生成测试数据
        1.生成实际中心为centers的测试样本300个，
        2.Xn是包含150个(x,y)点的二维数组
        3.labels_true为其对应的真是类别标签
    """
    # 生成的测试数据的中心点
    centers = [[1, 1], [-1, -1], [1, -1]]
    # 生成数据
    X, label_true = make_blobs(n_samples=15000, centers=centers, cluster_std=0.5, random_state=0)
    # return X, label_true
    return X

def plot(class_cen, X, c_list):
    # 画图
    colors = ['red', 'blue', 'black', 'green', 'yellow']
    plt.figure(figsize=(8, 6))
    plt.xlim([-3, 3])
    plt.ylim([-3, 3])
    for i in range(len(X)):
        d1 = Xn[i]
        d2 = Xn[c_list[i]]
        c = class_cen.index(c_list[i])
        plt.plot([d2[0], d1[0]], [d2[1], d1[1]], color=colors[c], linewidth=1)
        # if i == c_list[i] :
        #    plt.scatter(d1[0],d1[1],color=colors[c],linewidth=3)
        # else :
        #    plt.scatter(d1[0],d1[1],color=colors[c],linewidth=1)
    plt.savefig('AP 聚类.png')
    plt.show()

def simi_matrix(Xn):
    simi = []
    for m in Xn:
        ##每个数字与所有数字的相似度列表，即矩阵中的一行
        temp = []
        for n in Xn:
             ##采用负的欧式距离计算相似度
            s =-np.sqrt((m[0]-n[0])**2 + (m[1]-n[1])**2 + (m[2]-n[2])**2 + (m[3]-n[3])**2 + (m[4]-n[4])**2 + (m[5]-n[5])**2)
            temp.append(s)
        simi.append(temp)
    return simi

def accuracy(prediction, labels):
    return np.mean(np.sqrt(np.sum((prediction - labels) ** 2, 1)))

def knn_reg(off_rss,off_loc,trace,rss,k):
    # uniform 本节点所有邻节点投票权重一样
    # weight 投票权重
    knn_reg = neighbors.KNeighborsRegressor(k, weights='uniform', metric='euclidean')
    # print(knn_reg)
    knn_reg.fit(off_rss, off_loc)
    predictions = knn_reg.predict(rss)
    print(predictions - trace)
    plt_loc_rea(predictions,trace,name='预测后的点与真实点对比'+str(k))
    acc = accuracy(predictions, trace)
    print("acc:", acc , "m")
    # for i in range(len(predictions)):
    #     print(predictions[i],trace[i])
    return acc / 100
def plt_loc(data,name):
    plt.figure(figsize=(20, 15))
    plt.xticks(fontsize=24)
    plt.yticks(fontsize=24)
    plt.scatter(data[:, 0], data[:, 1])
    plt.savefig(name)
    plt.show()
def plt_loc_rea(pre,data,name):
    plt.figure(figsize=(20, 15))
    plt.xticks(fontsize=24)
    plt.yticks(fontsize=24)
    plt.scatter(data[:, 0], data[:, 1])
    plt.scatter(pre[:, 0], pre[:, 1])
    plt.savefig(name)
    plt.show()
def plt_ap_loc(yhat,clusters,data,name):
    plt.figure(figsize=(15, 10))
    # 为每个群集的样本创建散点图
    for cluster in clusters:
        # 获取此群集的示例的行索引
        row_ix = where(yhat == cluster)
        print(row_ix)
        # 创建这些样本的散布
        plt.scatter(data[row_ix, 0], data[row_ix, 1])
    # # 绘制散点图
    plt.xticks(fontsize=24)
    plt.yticks(fontsize=24)
    plt.savefig(name)
    plt.show()
if __name__ == '__main__':

    offline_data = scio.loadmat('sim_data/offline_data_random.mat')
    online_data = scio.loadmat('sim_data/online_data.mat')

    # 离线数据
    offline_location = offline_data['offline_location']
    offline_rss = offline_data['offline_rss']
    offline_rss = offline_rss[:2000]
    offline_location = offline_location[:2000]

    # 离线数据
    path16 = 'D:/Python workspace/chan/channels_July16.mat'
    data16 = h5.File(path16, 'r')
    off_rss = data16['RSSI'][:]
    off_xy = data16['labels'][:]
    # 在线数据
    path18 = 'D:/Python workspace/chan/channels_July18.mat'

    data18 = h5.File(path18, 'r')
    # print(data18['RSSI'][1:2][0:100])
    on_rss = data18['RSSI'][:]
    on_xy = data18['labels'][:]
    # 离线轨迹
    plt.scatter(off_xy[0][:], off_xy[1][:])
    plt.show()
    # 在线轨迹
    plt.scatter(on_xy[0][::100], on_xy[1][::100])
    plt.show()
    off_rss = off_rss.T
    off_xy = off_xy.T
    on_rss = on_rss.T
    on_xy = on_xy.T
    x = data16.keys()
    print(x)
    # print(on_xy)
    for i in range(on_xy.shape[0]):
        print(on_xy[i][1])

    print(data16['xLabels'][:])
    on_rss = on_rss[::100]
    on_xy = on_xy[::100]

    np.set_printoptions(threshold=np.inf)
    # print(on_rss.shape)
    # print(on_xy.shape)
    # print(off_rss.shape)
    # print(off_xy.shape)
    # print('onxy')
    # print(on_xy[1000][0])
    # for i in range(on_xy.shape[0]):
    #     print(on_xy[i][0])

    knn_reg(off_rss,off_xy,on_xy,on_rss,5)

    # # 在线数据
    # trace, rss = online_data['trace'][:200], online_data['rss'][:200]
    # # print('未ap聚类的值')
    # sum_ap = 0
    # for i in range(5,21):
    #     print('第',i,'次')
    #     sum_ap += knn_reg(offline_rss, offline_location, trace, rss,i)
    # print(sum_ap / 16)
    # # 离线真实位置
    # plt_loc(offline_location,'离线收集实际位置')
    # #  在线轨迹图
    # plt_loc(trace,'在线测试实际位置')
    p = -100

    # data = np.append(offline_rss,rss,axis=0)
    # loc = np.append(offline_location,trace,axis=0)
    # print(data)
    # print(data.shape)
    print(off_rss.shape)
    ap = AffinityPropagation(damping=0.5, max_iter=500, convergence_iter=30, preference=p).fit(off_rss[:5000])
    yhat = ap.predict(offline_rss)

    # # 检索唯一群集
    # clusters = unique(yhat)
    # print('clusters.shape',clusters.shape)
    # # plt_ap_loc(yhat,clusters,data)
    # plt_ap_loc(yhat, clusters, offline_rss, '亲和聚类后的rss值分布')
    # plt_ap_loc(yhat, clusters, offline_location, '亲和聚类后的实际位置值分布')
    #
    # rw = where(yhat == 1)
    # print(rw)
    # offline_rss = offline_rss[rw]
    # print(offline_rss.shape)
    # offline_location = offline_location[rw]
    #
    # p = -3000  ##3个中心
    # # simi = simi_matrix(offline_rss)
    # # p = np.median(simi)
    # # p = np.min(9)  ##9个中心，
    # # p = np.median(simi)  ##13个中心
    #
    # # ap = AffinityPropagation(damping=0.9, max_iter=500, convergence_iter=30, preference=p).fit(offline_rss)
    # # cluster_centers_indices = ap.cluster_centers_indices_
    # # # 为每个示例分配一个集群
    # # yhat = ap.predict(offline_rss)
    # # # 检索唯一群集
    # # clusters = unique(yhat)
    # # plt_ap_loc(yhat,clusters,offline_location)
    # # plt_ap_loc(yhat,clusters,offline_rss)
    #
    #
    # # rw = where(yhat == 0)
    # # offline_rss = offline_rss[rw]
    # # offline_location = offline_location[rw]
    # # print(offline_rss)
    # #
    # yhat = ap.predict(rss)
    # # 检索唯一群集
    # clusters = unique(yhat)
    # # plt_ap_loc(yhat,clusters,rss)
    # # plt_ap_loc(yhat, clusters, trace)
    # print('yhat:',yhat)
    # rw = where(yhat == 1)
    # trace = trace[rw]
    # rss = rss[rw]
    # sum_knn_ap = 0
    # for i in range(5,21):
    #     print('第',i,'次')
    #     sum_knn_ap += knn_reg(offline_rss,offline_location,trace,rss,i)
    # print(sum_knn_ap / 16)
    #
    # # for i in range(offline_rss.shape[0]):
    # #     plt.scatter(i,offline_rss[i][0])
    # # plt.show()
